﻿namespace SharpF2.ModelView
{
	using System;
	using System.ComponentModel;
	using System.Text.RegularExpressions;

	/// <summary>
	/// Define a filter that execute a regex replace on a string
	/// </summary>
	[Serializable]
	public class ReplaceFilter : INotifyPropertyChanged, IComparable<ReplaceFilter>
	{
		#region Events

		/// <summary>
		/// Event raised when a property has changed.
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="ReplaceFilter" /> class. 
		/// Constructor.
		/// </summary>
		/// <param name="pattern">The regular expression pattern to match.</param>
		/// <param name="replacement">The replacement string.</param>
		public ReplaceFilter(string pattern, string replacement)
		{
			Pattern = pattern;
			Replacement = replacement;
		}

		public ReplaceFilter()
		{
			Pattern = String.Empty;
			Replacement = String.Empty;
		}

		#endregion

		#region IComparable<ReplaceFilter> Members

		public int CompareTo(ReplaceFilter other)
		{
			var a = Pattern.CompareTo(other.Pattern);
			var b = Replacement.CompareTo(other.Replacement);

			return (a == 0 && b == 0) ? 0 : a;
		}

		#endregion

		#region Private Attributes

		/// <summary>
		/// The pattern of the regex replace 
		/// </summary>
		private string pattern;

		/// <summary>
		/// The replacement of the regex replace 
		/// </summary>
		private string replacement;

		#endregion

		#region Public Properties

		public string LastPattern { get; private set; }

		public string LastReplacement { get; private set; }

		/// <summary>
		/// Gets or sets the regular expression pattern to match.
		/// </summary>
		public string Pattern
		{
			get { return pattern; }

			set
			{
				LastPattern = pattern;
				pattern = value;
				NotifyPropertyChanged("Pattern");
			}
		}

		/// <summary>
		/// Gets or sets the replacement string.
		/// </summary>
		public string Replacement
		{
			get { return replacement; }

			set
			{
				LastReplacement = replacement;
				replacement = value;
				NotifyPropertyChanged("Replacement");
			}
		}

		#endregion

		#region Public Members

		public override bool Equals(object obj)
		{
			var replaceFilter = obj as ReplaceFilter;
			if (null == replaceFilter) return false;

			return Pattern.Equals(replaceFilter.Pattern) && Replacement.Equals(replaceFilter.Replacement);
		}

		public override int GetHashCode()
		{
			return String.Concat(Pattern, Replacement).GetHashCode();
		}

		/// <summary>
		/// Within a specified input string, replaces all strings that 
		/// match a specified regular expression with a specified replacement string.
		/// </summary>
		/// <param name="input">The specified input string.</param>
		/// <returns>
		/// A new string that is identical to the input string, 
		/// except that a replacement string takes the place of each matched string.
		/// </returns>
		public string Filter(string input)
		{
			var output = String.Empty;
			try
			{
				output = Regex.Replace(input, Pattern, Replacement);
			}
			catch (ArgumentNullException)
			{
			}

			return output;
		}

		#endregion

		#region Private Members

		/// <summary>
		/// Raise the event PropertyChanged.
		/// </summary>
		/// <param name="info">The PropertyName.</param>
		private void NotifyPropertyChanged(string info)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(info));
			}
		}

		#endregion
	}
}